/**
 *
 */
package jp.seraph.jsade.task;

import java.util.ArrayList;
import java.util.List;

import jp.seraph.jsade.core.Player;
import jp.seraph.jsade.core.World;
import jp.seraph.jsade.util.Executor;

/**
 *
 *
 */
public abstract class AbstractTask implements AgentTask {
    public AbstractTask(){
        mCompletedListeners = new ArrayList<Executor>();
        mCanceledListeners = new ArrayList<Executor>();
        mInitiatedListeners = new ArrayList<Executor>();
        mRunning = false;
    }

    private List<Executor> mCompletedListeners;
    private List<Executor> mCanceledListeners;
    private List<Executor> mInitiatedListeners;
    private boolean mRunning;

    /**
     *
     * @see jp.seraph.jsade.task.AgentTask#isRunning()
     */
    public boolean isRunning() {
        return mRunning;
    }

    /**
     *
     * @see jp.seraph.jsade.task.AgentTask#canExecute()
     */
    public boolean canExecute() {
        return true;
    }

    /**
     *
     * @see jp.seraph.jsade.task.AgentTask#addCanceledListener(jp.seraph.jsade.util.Executor)
     */
    public void addCanceledListener(Executor aListener) {
        mCanceledListeners.add(aListener);
    }

    /**
     *
     * @see jp.seraph.jsade.task.AgentTask#addCompletedListener(jp.seraph.jsade.util.Executor)
     */
    public void addCompletedListener(Executor aListener) {
        mCompletedListeners.add(aListener);
    }

    /**
     *
     * @see jp.seraph.jsade.task.AgentTask#execute(jp.seraph.jsade.core.World, jp.seraph.jsade.core.Player)
     */
    public abstract void execute(World aWorld, Player aPlayer);

    /**
     *
     * @see jp.seraph.jsade.task.AgentTask#init()
     */
    public void init(){
        mRunning = true;
        fireInitiated();
    }

    /**
     *
     * @see jp.seraph.jsade.task.AgentTask#cancel()
     */
    public void cancel() {
        mRunning = false;
        fireCanceled();
    }

    /**
     *
     * @see jp.seraph.jsade.task.AgentTask#removeCanceledListener(jp.seraph.jsade.util.Executor)
     */
    public void removeCanceledListener(Executor aListener) {
        mCanceledListeners.remove(aListener);
    }

    /**
     *
     * @see jp.seraph.jsade.task.AgentTask#removeCompletedListener(jp.seraph.jsade.util.Executor)
     */
    public void removeCompletedListener(Executor aListener) {
        mCompletedListeners.remove(aListener);
    }

    /**
     *
     * @see jp.seraph.jsade.task.AgentTask#addInitiatedListener(jp.seraph.jsade.util.Executor)
     */
    public void addInitiatedListener(Executor aListener) {
        mInitiatedListeners.add(aListener);
    }

    /**
     *
     * @see jp.seraph.jsade.task.AgentTask#removeInitiatedListener(jp.seraph.jsade.util.Executor)
     */
    public void removeInitiatedListener(Executor aListener) {
        mInitiatedListeners.remove(aListener);
    }

    protected void complete(){
        mRunning = false;
        fireCompleted();
        mCompletedListeners.clear();
        mCanceledListeners.clear();
        mInitiatedListeners.clear();
    }

    private void fireCompleted(){
        for (Executor tListener : mCompletedListeners) {
            tListener.execute();
        }
    }

    private void fireCanceled(){
        for (Executor tListener : mCanceledListeners) {
            tListener.execute();
        }
    }

    private void fireInitiated(){
        for (Executor tListener : mInitiatedListeners) {
            tListener.execute();
        }
    }
}
